package com.xm.email.util;

import com.sun.mail.util.MailSSLSocketFactory;
import com.xm.email.core.MailInfo;
import com.xm.email.core.MyAuthenticator;
import lombok.extern.slf4j.Slf4j;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * 邮件推送类
 */
@Slf4j
public class SimpleEmailUtil {

	/**
	 * 获得邮件会话属性
	 */
	public Properties getProperties(MailInfo mailInfo) {
		Properties p = new Properties();
		p.put("mail.smtp.host", mailInfo.getMailServerHost());
		p.put("mail.smtp.port", mailInfo.getMailServerPort());
		p.put("mail.smtp.auth", mailInfo.isValidate() ? "true" : "false");
		//-------当需使用SSL验证时添加，邮箱不需SSL验证时删除即可（测试SSL验证使用QQ企业邮箱）
		if(mailInfo.isSsl()) {
			String SSL_FACTORY="javax.net.ssl.SSLSocketFactory";
			p.put("mail.smtp.socketFactory.class", SSL_FACTORY);
			p.put("mail.smtp.socketFactory.fallback", "false");
			p.put("mail.smtp.socketFactory.port", mailInfo.getMailServerPort());

			//参考https://help.aliyun.com/document_detail/2679644.html
//			p.put("mail.smtp.ssl.enable", true);
//			p.put("mail.smtp.ssl.protocols", "TLSv1.2");

			//参考https://blog.csdn.net/wl1411956542/article/details/129196136
//			p.put("mail.mime.splitlongparameters", true);//据说高版本可能会出现因截断而引发的乱码问题

			MailSSLSocketFactory sf=null;
			try {
				sf = new MailSSLSocketFactory();
				sf.setTrustAllHosts(true);
			} catch (GeneralSecurityException e) {
				log.error("创建邮件ssl socketFactory异常！", e);
			}
			p.put("mail.smtp.ssl.socketFactory", sf);
		}
		return p;
	}

	/**
	 * 发送文本/网页邮件
	 * @param mailInfo 邮件详情
	 */
	public void sendMail(MailInfo mailInfo) throws Exception {
		log.info("发送邮件，创建发送邮件session");
		long start = System.currentTimeMillis();
		//判断是否需要身份认证
		MyAuthenticator authenticator = null;
		if (mailInfo.isValidate()) {
			//如果需要身份认证，则创建一个密码验证器
			authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		//根据邮件会话属性和密码验证器构造一个发送邮件的session
		Properties pro = getProperties(mailInfo);
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);

		//根据session创建一个邮件消息
		Message mailMessage = new MimeMessage(sendMailSession);
		//创建邮件发送者地址
		Address from = new InternetAddress(mailInfo.getFromAddress());
		//设置邮件消息的发送者
		mailMessage.setFrom(from);
		//创建邮件的接收者地址，并设置到邮件消息中
		Address to = new InternetAddress(mailInfo.getToAddress());
		mailMessage.setRecipient(Message.RecipientType.TO, to);
		//设置邮件消息的主题
		mailMessage.setSubject(mailInfo.getSubject());
		//设置邮件消息发送的时间
		mailMessage.setSentDate(new Date());
		//设置邮件消息的主要内容
		String mailContent = mailInfo.getContent();
		mailMessage.setText(mailContent);

		//判断文件内容是文本 还是页面
		if(mailInfo.isHtml()){
			//MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
			Multipart mainPart = new MimeMultipart();
			//创建一个包含HTML内容的MimeBodyPart
			BodyPart html = new MimeBodyPart();
			//设置HTML内容
			html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
			mainPart.addBodyPart(html);

			List<String> fileList = mailInfo.getFileList();
			//遍历添加附件，并编码文件名称
			if (fileList != null && !fileList.isEmpty()) {
				List<File> files = mailInfo.getFiles();
				if(files.isEmpty()){
					files = new ArrayList<>();
				}

				for (String path : fileList){
					files.add(new File(path));
				}
				for (File file : files) {
					BodyPart attachmentBodyPart = new MimeBodyPart();
					DataSource source = new FileDataSource(file);
					attachmentBodyPart.setDataHandler(new DataHandler(source));
					attachmentBodyPart.setFileName(MimeUtility.encodeText(file.getName()));
					mainPart.addBodyPart(attachmentBodyPart);
				}
			}
			//将MiniMultipart对象设置为邮件内容
			mailMessage.setContent(mainPart);
			//保存邮件
			mailMessage.saveChanges();
		}

		//发送邮件
		Transport.send(mailMessage);
		log.info("发送邮件，发送成功。耗时={}s", (System.currentTimeMillis() - start) /1000L);
	}

	/*public static void sendEmail(SysEmail sysEmail) throws Exception {
		MailConf mConf = SpringUtils.getBean(MailConf.class);
		MailInfo mailInfo = new MailInfo();
		mailInfo.setMailServerHost(mConf.getEmailSmtp());
		mailInfo.setMailServerPort(mConf.getEmailPort());
		mailInfo.setValidate(true);
		mailInfo.setSsl(true);
		mailInfo.setUserName(mConf.getEmailAccount());//邮箱账号
		mailInfo.setPassword(mConf.getEmailPassword());//邮箱授权码
		mailInfo.setFromAddress(mailInfo.getUserName());//发件人地址
		mailInfo.setToAddress(sysEmail.getReceiversEmail());//收件人地址
		mailInfo.setSubject(sysEmail.getTitle());
		mailInfo.setContent(sysEmail.getContent());

		SimpleEmailUtil sms = new SimpleEmailUtil();

		//发送
		sms.sendMail(mailInfo);
	}*/

}
